package com.org.oracle.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.org.oracle.enums.ResponseCodeEnum;
import com.org.oracle.mapper.TopicMapper;
import com.org.oracle.mongodb.entity.Chapter;
import com.org.oracle.mongodb.entity.Circle;
import com.org.oracle.mysql.entity.Topic;
import com.org.oracle.mysql.vo.HistoryTopicVO;
import com.org.oracle.mysql.vo.TopicVO;
import com.org.oracle.service.TopicService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author heiye
 * @version 1.0
 * @data 2024/8/18 下午4:47
 */
@Service
public class TopicServiceImpl extends ServiceImpl<TopicMapper, Topic> implements TopicService {

    @Autowired
    private TopicMapper topicMapper;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 查找全部话题AI标签
     */
    @Override
    public List<TopicVO> findAll() {
        List<Topic> topics = topicMapper.selectList(
                Wrappers.<Topic>lambdaQuery()
                        .select(Topic::getId, Topic::getName, Topic::getIntroduce, Topic::getCircleId, Topic::getAttractTitle)
        );

        // 初始化 VO 数据
        List<TopicVO> topicVOS = Lists.newArrayList();
        // 循环填入 VO 数据
        for (Topic topic : topics) {
            TopicVO topicVO = new TopicVO();
            // copy 数据 到 VO 中
            BeanUtils.copyProperties(topic, topicVO);
            // 添加到 topicVOS 中
            topicVOS.add(topicVO);
        }
        return topicVOS;
    }

    /**
     * 根据知识圈 id 查找对应的话题 ai
     */
    @Override
    public List<TopicVO> findByCircleId(String circleId, String size) {
        // 校验参数
        Preconditions.checkArgument(StringUtils.isNotBlank(circleId), ResponseCodeEnum.PARAM_REQUIRE);

        // 查询数据
        List<Topic> topics = topicMapper.selectList(
                Wrappers.<Topic>lambdaQuery()
                        .select(Topic::getId, Topic::getName, Topic::getIntroduce, Topic::getCircleId, Topic::getAttractTitle)
                        .eq(Topic::getCircleId, circleId)
                        .orderByDesc(Topic::getWeight)
                        .last("LIMIT " + size)
        );

        // 初始化 VO 数据
        List<TopicVO> topicVOS = Lists.newArrayList();
        // 循环填入 VO 数据
        for (Topic topic : topics) {
            TopicVO topicVO = new TopicVO();
            // copy 数据 到 VO 中
            BeanUtils.copyProperties(topic, topicVO);
            // 添加到 topicVOS 中
            topicVOS.add(topicVO);
        }
        return topicVOS;
    }

    @Override
    public List<Topic> info() {
        //先找章节
        List<Chapter> chapters = mongoTemplate.findAll(Chapter.class);
        List<Topic> topicList = new ArrayList<Topic>();
        //再根据每一个章节循环的去填充对应的话题ai
        for (Chapter chapter : chapters) {
            String circleId = chapter.getCircleId();
            Query query = new Query();
            query.addCriteria(Criteria.where("circleId").is(circleId));
            Circle circle = mongoTemplate.findOne(query, Circle.class);
            System.out.println(circle);
            chapter.getTestingPoints().forEach(testingPoint -> {
                Topic topic = new Topic();
                topic.setCircleId(circleId);
                topic.setName(testingPoint.getName());
                topic.setIntroduce(testingPoint.getSummary());
                topic.setAiKey(circle.getAiKey());
                topic.setChapter(testingPoint.getOrdinal());
                topic.setAvatar(circle.getAvatar());
                //保存到ai表里
                //检查circle_id和chapter字段的语句
                QueryWrapper<Topic> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("circle_id", circleId).eq("chapter", "01");
                if (topicMapper.selectOne(queryWrapper) != null) {
                    topicMapper.updateById(topic);
                } else
                    topicMapper.insert(topic);
                topicList.add(topic);
            });
        }
        return topicList;
    }

    @Override
    public List<TopicVO> findGoods(int size) {
        // 分页
        IPage<Topic> page = new Page<>(1, size);

        //想要得到权重最高的size个话题
        List<Topic> topics = topicMapper.selectList(
                page,
                Wrappers.<Topic>lambdaQuery()
                        .select(Topic::getId, Topic::getName, Topic::getIntroduce, Topic::getCircleId, Topic::getAttractTitle)
                        .orderByDesc(Topic::getWeight)
                        .last("LIMIT " + size)
        );
        // 初始化 VO 数据
        List<TopicVO> topicVOS = Lists.newArrayList();
        // 循环填入 VO 数据
        for (Topic topic : topics) {
            TopicVO topicVO = new TopicVO();
            // copy 数据 到 VO 中
            BeanUtils.copyProperties(topic, topicVO);
            // 添加到 topicVOS 中
            topicVOS.add(topicVO);
        }

        return topicVOS;

    }

    @Override
    public Object updateWeight(String id, int type) {
        int weight = 0;
        String point = stringRedisTemplate.opsForValue().get("topic_weight_" + id);
        if (point != null)
            weight = Integer.parseInt(point);
        if (String.valueOf(type).equals("1"))
            stringRedisTemplate.opsForValue().set("topic_weight_" + id, weight + 1 + "");
        else
            stringRedisTemplate.opsForValue().set("topic_weight_" + id, weight + 2 + "");
        return null;
    }

    /**
     * 查询话题 AI 详情
     *
     * @param id
     * @return
     */
    @Override
    public Topic findById(String id) {
        return findOneById(id);
    }

    @Override
    public TopicVO findTopicById(String id) {
        Topic topic = findOneById(id);
        TopicVO topicVO = new TopicVO();
        BeanUtils.copyProperties(topic, topicVO);
        return topicVO;
    }

    @Override
    public List<TopicVO> findAllById(String id) {
        List<Topic> topics = topicMapper.selectList(
                Wrappers.<Topic>lambdaQuery()
                        .select(Topic::getId, Topic::getName, Topic::getAttractTitle)
                        .eq(Topic::getCircleId, id)
                        .orderByDesc(Topic::getWeight)
        );
        // 初始化 VO 数据
        List<TopicVO> topicVOS = Lists.newArrayList();
        // 循环填入 VO 数据
        for (Topic topic : topics) {
            TopicVO topicVO = new TopicVO();
            // copy 数据 到 VO 中
            BeanUtils.copyProperties(topic, topicVO);
            // 添加到 topicVOS 中
            topicVOS.add(topicVO);
        }
        return topicVOS;
    }

    @Override
    public HistoryTopicVO findHistoryVOById(String topicId) {
        Topic topic = findById(topicId);
        HistoryTopicVO topicVO = new HistoryTopicVO();
        BeanUtils.copyProperties(topic, topicVO);
        return topicVO;
    }

    //封装一个通过id找Topic的方法
    public Topic findOneById(String id) {
        //因为在MongoDB里面id固定是Long  但是我们规定了是Sting 所以在查找的时候把他换一下类型就好了
        return topicMapper.selectOne(
                Wrappers.<Topic>lambdaQuery()
                        .select(Topic::getId
                                , Topic::getName
                                , Topic::getIntroduce
                                , Topic::getCircleId
                                , Topic::getAttractTitle
                                , Topic::getWeight
                                , Topic::getAvatar
                                , Topic::getAiKey
                                , Topic::getChapter)
                        .eq(Topic::getId, Long.parseLong(id))
        );
    }
}
